import { Command } from '../utils/cli-handler.js';
import { logger } from '../../core/logger.js';
import { RoboPlay } from '../../roboplay/client.js';
import { composeColors, color } from '../../core/color.js';
import { Spinner } from '../utils/spinner.js';
import { openBrowser, sleep } from '../utils/utils.js';
import { KeyWatcher } from '../utils/key-watcher.js';
import { RoboPlaySession } from '../../roboplay/session.js';
import { Mode } from '../../core/mode.js';
import { Env } from '../../core/env.js';

const command = new Command("login").description("Sign in to your RoboPlay account").option("-s", "--silent", "do not print anything").option("-v", "--verbose", "print more information for debugging").option("-h", "--help", "Shows the available command options").handler(loginAction);
var login_default = command;
const Indent = "   ";
const OAuthTimeout = 10 * 60 * 1e3;
async function loginAction(_args, options) {
  logger({
    enabled: !options.silent,
    level: options.verbose ? "debug" : "info"
  });
  if (!process.env.NODE_ENV) {
    process.env.NODE_ENV = "production";
  }
  const defaultMode = Mode.get();
  await Env.load({ mode: defaultMode });
  const oauthSession = await RoboPlay.OAuth.create();
  let sessionStatus = oauthSession.status;
  if (!oauthSession.success) {
    logger.error(oauthSession.error);
    return;
  }
  const cta = composeColors(color.bold, color.cyan)("Press Enter");
  logger.log("\n" + Indent, color.bold(`\u2728 Welcome to ${color.yellow("RoboPlay")}`));
  logger.log("\n" + Indent, color.bold("\u{1F310} Ready to start your journey?"));
  logger.log(Indent + "   ", `${cta} to open your web browser...`);
  logger.log("\n" + Indent, color.bold("\u{1F517} Prefer to navigate manually?"));
  logger.log(Indent + "   ", color.blue(oauthSession.url), "\n");
  const spinner = new Spinner(Indent + ` {{spinner}}  Waiting for sign in...`);
  spinner.start();
  const keyWatcher = new KeyWatcher(() => {
    spinner.stop();
    logger.log("\x1B[2A\x1B[J");
    logger.log("\n" + Indent, color.dim("Opening browser..."), "\n");
    openBrowser(oauthSession.url);
    spinner.start();
  });
  keyWatcher.start();
  const pollStart = Date.now();
  while (!["Authorized", "Expired", "Invalid", "Used"].includes(sessionStatus)) {
    await sleep(4e3);
    const pollResult = await RoboPlay.OAuth.poll({ token: oauthSession.token });
    sessionStatus = pollResult.status;
    if (Date.now() - pollStart > OAuthTimeout) {
      spinner.stop();
      keyWatcher.stop();
      logger.error(`Timed out waiting for OAuth session to be authorized.`);
      return;
    }
  }
  spinner.stop();
  keyWatcher.stop();
  logger.debug(`Completed OAuth session status: ${sessionStatus}`);
  const badColor = composeColors(color.bold, color.red);
  if (["Expired", "Invalid", "Used"].includes(sessionStatus)) {
    logger.error(`This OAuth session is ${badColor(sessionStatus.toLowerCase())}. Please try again.`);
    return;
  }
  const verifyResult = await RoboPlay.OAuth.verify({
    secret: oauthSession.secret,
    token: oauthSession.token
  });
  if (!verifyResult.success || !verifyResult.user || !verifyResult.userToken) {
    logger.error(`Failed to verify OAuth session with status:`, badColor(verifyResult.status));
    return;
  }
  const pods = await RoboPlay.Pod.list({
    bearerToken: verifyResult.userToken,
    userId: verifyResult.user.id
  });
  await RoboPlaySession.save({
    linkedProjects: {},
    pods: pods.data,
    robos: [],
    user: verifyResult.user,
    userToken: verifyResult.userToken
  });
  const pod = pods.data[0];
  await RoboPlaySession.link(pod.id);
  logger.log("\n" + Indent, `Linked project to Pod ${composeColors(color.bold, color.cyan)(pod.name)}.`);
  const userName = verifyResult.user.displayName ?? verifyResult.user.email;
  logger.log("\n" + Indent, color.green(`\u{1F389} You are now signed in as ${color.bold(userName)}.
`));
}

export { login_default as default, loginAction };
